/*
 * Synchronizer.h
 *
 *  Created on: 26/11/2008
 *      Author: fernando
 */

#ifndef SYNCHRONIZER_H_
#define SYNCHRONIZER_H_

/**
 * Interfaces para classes sincronizáveis.
 *
 * @see Synchronizer
 * @author Fernando Souza
 */
class Synchronizable {
public:
	/**
	 * Evento de sincronia. A cada ciclo o sincronizador dispara este evento com
	 * o tempo passado desde o ciclo anterior.
	 *
	 * @param seconds_past Segundos passados desde o ciclo anterior.
	 */
	virtual void synch(double const& seconds_past) = 0;
};

/**
 * O Sincronizador. Esta classe é responsável por sincronizar os ciclos de
 * processamento. Cada ciclo deve ter aproximadamente o mesmo tempo de execução.
 * Caso algum ciclo extrapole este tempo o excesso não será descontado do
 * próximo ciclo, que terá seu tempo de execução garantido.
 *
 * @author Fernando Souza
 */
class Synchronizer {

	/**
	 * Ponteiro para o objeto sincronizado.
	 */
	Synchronizable* _process;

	/**
	 * Booleano para interrupção da sincronia. Quando verdadeiro pára a
	 * sincronização a partir do próximo ciclo.
	 */
	bool _stop;

	/**
	 * Tempo em segundos estimado para duração de cada ciclo.
	 */
	double _interval;

public:

	/**
	 * Construtor da classe.
	 *
	 * @param process Instância do objeto sincronizado.
	 */
	Synchronizer(Synchronizable& process);

	/**
	 * Construtor da classe.
	 *
	 * @param process Instância do objeto sincronizado.
	 * @param cycles_per_second Quantidade de ciclos por segundo.
	 */
	Synchronizer(Synchronizable& process, int cycles_per_second);

	/**
	 * Destrutor da classe.
	 */
	virtual ~Synchronizer();

	/**
	 * Dispara o processo de sincronização. Este processo divide o segundo em
	 * ciclos e garante que cada ciclo tenha o mesmo tempo mínimo de execução.
	 * Caso um ciclo sofra atraso, o tempo do próximo ciclo não sofrerá
	 * descontos, isto é, será mantido o tempo mínimo de execução de cada ciclo.
	 *
	 * @see stop()
	 */
	void run();

	/**
	 * Interrompe o processo de sincronização. O processo de sincronização é
	 * interrompido já no processamento do próximo ciclo.
	 *
	 * @see run()
	 */
	void stop();
};

#endif /* SYNCHRONIZER_H_ */
